package yxy.game.pm2.module.arena.toparena;

import org.joda.time.DateTime;
import yxy.apple.logger.Logger;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.battle.module.record.result.BattleResult;
import yxy.cherry.data.bean.dfsjingcai;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.bean.Constant;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.currency.Currencies;
import yxy.game.pm2.bean.module.BaseGameRedisBean;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.module.battle.BattleModule;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @ClassName TopAreanModule
 * @Author jingtao-zheng
 * @Date 2022/9/17 14:02
 * @Version 1.0
 **/
public class TopAreanModule extends BaseGameRedisBean {
    protected static Logger logger = Logger.create(TopAreanModule.class);

    private int areaId;//区id
    private String code;//活动代号,为了区分玩家有没有参加本期活动

    //8个小组赛记录赛程
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group1 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group2 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group3 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group4 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group5 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group6 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group7 = new HashMap<>();
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group8 = new HashMap<>();

    //冠军赛记录赛程
    private HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> finals = new HashMap<>();


    private DateTime startTime;//开始时间
    private TopAreanHandle.TopAreanEnum state;//该区当前活动所处状态
    private HashMap<TopAreanHandle.TopAreanEnum, DateTime> stateTimes = new HashMap<>();//区活动状态,时间表
    private List<String> plyaerCodes = new ArrayList<>();//所有参数玩家

    private boolean isRunning;//活动是否在运行中,全部结算完成就改为false


    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup1() {
        return group1;
    }

    public void setGroup1(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group1) {
        this.group1 = group1;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup2() {
        return group2;
    }

    public void setGroup2(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group2) {
        this.group2 = group2;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup3() {
        return group3;
    }

    public void setGroup3(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group3) {
        this.group3 = group3;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup4() {
        return group4;
    }

    public void setGroup4(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group4) {
        this.group4 = group4;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup5() {
        return group5;
    }

    public void setGroup5(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group5) {
        this.group5 = group5;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup6() {
        return group6;
    }

    public void setGroup6(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group6) {
        this.group6 = group6;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup7() {
        return group7;
    }

    public void setGroup7(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group7) {
        this.group7 = group7;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getGroup8() {
        return group8;
    }

    public void setGroup8(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group8) {
        this.group8 = group8;
    }

    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> getFinals() {
        return finals;
    }

    public void setFinals(HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> finals) {
        this.finals = finals;
    }

    public int getAreaId() {
        return areaId;
    }

    public void setAreaId(int areaId) {
        this.areaId = areaId;
    }

    public boolean isRunning() {
        return isRunning;
    }

    public void setRunning(boolean running) {
        isRunning = running;
    }

    public DateTime getStartTime() {
        return startTime;
    }

    public void setStartTime(DateTime startTime) {
        this.startTime = startTime;
    }

    public HashMap<TopAreanHandle.TopAreanEnum, DateTime> getStateTimes() {
        return stateTimes;
    }

    public void setStateTimes(HashMap<TopAreanHandle.TopAreanEnum, DateTime> stateTimes) {
        this.stateTimes = stateTimes;
    }

    public TopAreanHandle.TopAreanEnum getState() {
        return state;
    }

    public void setState(TopAreanHandle.TopAreanEnum state) {
        this.state = state;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public List<String> getPlyaerCodes() {
        return plyaerCodes;
    }

    public void setPlyaerCodes(List<String> plyaerCodes) {
        this.plyaerCodes = plyaerCodes;
    }

    //======================================== func

    /**
     * 初始化时间表
     */
    public void resetState(DateTime startTime) {
        getStateTimes().clear();
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_PREPARE, startTime.plusDays(1).plusHours(5));//休赛日结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_GROUP, startTime.plusDays(1).plusHours(19));//小组赛准备结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_QUIZ64, startTime.plusDays(1).plusHours(20));//64强竞猜结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_QUIZ32, startTime.plusDays(1).plusHours(21));//32强竞猜结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_QUIZ16, startTime.plusDays(1).plusHours(22));//16强竞猜结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_OFFSEASONGROUP, startTime.plusDays(2).plusHours(5));//赛季小组赛结束展示时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_APEREADY, startTime.plusDays(2).plusHours(19));//冠军赛准备结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_QUIZ8, startTime.plusDays(2).plusHours(20));//8强竞猜结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_QUIZ4, startTime.plusDays(2).plusHours(21));//4强竞猜结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_QUIZ2, startTime.plusDays(2).plusHours(22));//决赛竞猜结束时间
        getStateTimes().put(TopAreanHandle.TopAreanEnum.STEP_OFFSEASON, startTime.plusDays(3).plusHours(5));//赛季结束展示时间
        logger.info("日志5：%s区,巅峰赛重置", getAreaId());
        setState(TopAreanHandle.TopAreanEnum.STEP_PREPARE);//设置当前状态,肯定是休赛日
        setRunning(true);//活动开启
        setStartTime(startTime);
        setCode(code(startTime));//赛季唯一code
        set();
        try {
            logger.info("日志6：%s区,巅峰赛重置完毕", getAreaId());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void endResetState(DateTime startTime) {
        getStateTimes().clear();
        setStartTime(startTime);
        setState(TopAreanHandle.TopAreanEnum.STEP_PREPARE);//设置当前状态,肯定是休赛日
        setRunning(false);//活动开启
        set();
    }

    static public String code(DateTime startTime) {
        String code = startTime.toString(Constant.yyyyMMdd);
        return code;
    }

    /**
     * 清除小组赛的赛程和冠军赛的赛程数据
     */
    public void clearGroupAndFinal() {
        getGroup1().clear();
        getGroup2().clear();
        getGroup3().clear();
        getGroup4().clear();
        getGroup5().clear();
        getGroup6().clear();
        getGroup7().clear();
        getGroup8().clear();
        getFinals().clear();
    }

    /**
     * 添加小组赛的64强赛程
     *
     * @param playerCodes 每组的8个玩家
     * @param groupId     第几组
     */
    public void addGrouping64(List<String> playerCodes, int groupId) {
        HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group = matchGroup(groupId);
        TopAreanStructure topAreanStructure12 = newSchedule(playerCodes.get(0), playerCodes.get(1), TopAreanHandle.TopAreanCode.F12, true, groupId);
        group.put(topAreanStructure12.getFinalCode(), topAreanStructure12);
        TopAreanStructure topAreanStructure34 = newSchedule(playerCodes.get(2), playerCodes.get(3), TopAreanHandle.TopAreanCode.F34, true, groupId);
        group.put(topAreanStructure34.getFinalCode(), topAreanStructure34);
        TopAreanStructure topAreanStructure56 = newSchedule(playerCodes.get(4), playerCodes.get(5), TopAreanHandle.TopAreanCode.F56, true, groupId);
        group.put(topAreanStructure56.getFinalCode(), topAreanStructure56);
        TopAreanStructure topAreanStructure78 = newSchedule(playerCodes.get(6), playerCodes.get(7), TopAreanHandle.TopAreanCode.F78, true, groupId);
        group.put(topAreanStructure78.getFinalCode(), topAreanStructure78);
    }

    /**
     * 添加小组赛的32强赛程
     *
     * @param playerCodes 每组已经排序好进入32强的4个玩家
     */
    public void addGrouping32(List<String> playerCodes, int groupId) {
        HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group = matchGroup(groupId);
        TopAreanStructure topAreanStructure12 = newSchedule(playerCodes.get(0), playerCodes.get(1), TopAreanHandle.TopAreanCode.F1256, true, groupId);
        group.put(topAreanStructure12.getFinalCode(), topAreanStructure12);
        TopAreanStructure topAreanStructure34 = newSchedule(playerCodes.get(2), playerCodes.get(3), TopAreanHandle.TopAreanCode.F3478, true, groupId);
        group.put(topAreanStructure34.getFinalCode(), topAreanStructure34);
    }

    /**
     * 添加小组赛的16强赛程
     *
     * @param playerCodes 每组已经排序好进入16强的2个玩家
     */
    public void addGrouping16(List<String> playerCodes, int groupId) {
        HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group = matchGroup(groupId);
        TopAreanStructure topAreanStructure12 = newSchedule(playerCodes.get(0), playerCodes.get(1), TopAreanHandle.TopAreanCode.FINAL, true, groupId);
        group.put(topAreanStructure12.getFinalCode(), topAreanStructure12);
    }

    /**
     * 添加冠军赛的8强赛程
     *
     * @param playerCodes 8强参数选手
     */
    public void addGrouping8(List<String> playerCodes, int groupId) {
        HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> finals = matchGroup(groupId);
        TopAreanStructure topAreanStructure12 = newSchedule(playerCodes.get(0), playerCodes.get(1), TopAreanHandle.TopAreanCode.F12, false, 9);
        finals.put(topAreanStructure12.getFinalCode(), topAreanStructure12);
        TopAreanStructure topAreanStructure34 = newSchedule(playerCodes.get(2), playerCodes.get(3), TopAreanHandle.TopAreanCode.F34, false, 9);
        finals.put(topAreanStructure34.getFinalCode(), topAreanStructure34);
        TopAreanStructure topAreanStructure56 = newSchedule(playerCodes.get(4), playerCodes.get(5), TopAreanHandle.TopAreanCode.F56, false, 9);
        finals.put(topAreanStructure56.getFinalCode(), topAreanStructure56);
        TopAreanStructure topAreanStructure78 = newSchedule(playerCodes.get(6), playerCodes.get(7), TopAreanHandle.TopAreanCode.F78, false, 9);
        finals.put(topAreanStructure78.getFinalCode(), topAreanStructure78);
    }

    /**
     * 添加冠军赛的4强赛程
     *
     * @param playerCodes 4强参数选手
     */
    public void addGrouping4(List<String> playerCodes, int groupId) {
        HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group = matchGroup(groupId);
        TopAreanStructure topAreanStructure12 = newSchedule(playerCodes.get(0), playerCodes.get(1), TopAreanHandle.TopAreanCode.F1256, true, groupId);
        group.put(topAreanStructure12.getFinalCode(), topAreanStructure12);
        TopAreanStructure topAreanStructure34 = newSchedule(playerCodes.get(2), playerCodes.get(3), TopAreanHandle.TopAreanCode.F3478, true, groupId);
        group.put(topAreanStructure34.getFinalCode(), topAreanStructure34);
    }

    /**
     * 添加冠军赛的2强赛程
     *
     * @param playerCodes 2强参数选手
     */
    public void addGrouping2(List<String> playerCodes, int groupId) {
        HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> group = matchGroup(groupId);
        TopAreanStructure topAreanStructureFINAL = newSchedule(playerCodes.get(0), playerCodes.get(1), TopAreanHandle.TopAreanCode.FINAL, true, groupId);
        group.put(topAreanStructureFINAL.getFinalCode(), topAreanStructureFINAL);
    }

    /**
     * 更新赛季运行状态
     */
    public void addGrouping() {
        setRunning(false);//赛季运行状态
    }


    /**
     * 初始化谁和谁打,并更新参赛人员状态
     *
     * @param isGroup 是否是小组赛标志
     * @param groupId 组id 小组1-8 冠军赛特殊组 9
     */
    private TopAreanStructure newSchedule(String player1, String player2, TopAreanHandle.TopAreanCode topAreanCode, boolean isGroup, int groupId) {
        TopAreanStructure topAreanStructure = new TopAreanStructure();

        topAreanStructure.setFinalCode(topAreanCode);

        TopAreanPlayer topAreanPlayer1 = new TopAreanPlayer();
        topAreanPlayer1.setPlayerCode(player1);
        topAreanStructure.setPlayer1(topAreanPlayer1);

        TopAreanPlayer topAreanPlayer2 = new TopAreanPlayer();
        topAreanPlayer2.setPlayerCode(player2);
        topAreanStructure.setPlayer2(topAreanPlayer2);

        //更新参赛人员状态
        TopAreanPlayerModule playerModule1 = TopAreanPlayerModule.get(player1);
        TopAreanPlayerModule playerModule2 = TopAreanPlayerModule.get(player2);

        playerModule1.setGroup(groupId);//玩家组别
        playerModule2.setGroup(groupId);
        playerModule1.setCode(getCode());//更新赛季code
        playerModule2.setCode(getCode());

        try {
            if (playerModule1.tryLock() && playerModule2.tryLock()) {
                if (isGroup) {
                    groupDealWith(playerModule1, playerModule2, topAreanCode);
                } else {
                    finalDealWith(playerModule1, playerModule2, topAreanCode);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            playerModule1.unlock();
            playerModule2.unlock();
        }
        return topAreanStructure;
    }

    //冠军赛处理 参赛人员数据处理
    private void finalDealWith(TopAreanPlayerModule playerModule1, TopAreanPlayerModule playerModule2, TopAreanHandle.TopAreanCode topAreanCode) {
        switch (topAreanCode) {
            case F12:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule1.setPos(1);//玩家位置
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule2.setPos(2);
                break;
            case F34:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule1.setPos(3);//玩家位置
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule2.setPos(4);
                break;
            case F56:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule1.setPos(5);//玩家位置
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule2.setPos(6);
                break;
            case F78:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule1.setPos(7);//玩家位置
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.Eight);
                playerModule2.setPos(8);
                break;
            case F1256:
            case F3478:
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.Four);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.Four);
                break;
            case FINAL:
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.RunnerUp);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.RunnerUp);
                break;
            default:
                break;
        }
        playerModule1.set();
        playerModule2.set();
    }

    //小组赛处理 参赛人员数据处理
    private void groupDealWith(TopAreanPlayerModule playerModule1, TopAreanPlayerModule playerModule2, TopAreanHandle.TopAreanCode topAreanCode) {
        switch (topAreanCode) {
            case F12:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule1.setPos(1);//玩家位置
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule2.setPos(2);
                break;
            case F34:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule1.setPos(3);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule2.setPos(4);
                break;
            case F56:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule1.setPos(5);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule2.setPos(6);
                break;
            case F78:
                //TODO 这个数据在赛季结束应该需要清除,暂时没看到在哪清除
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule1.setPos(7);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupEight);
                playerModule2.setPos(8);
                break;
            case F1256:
            case F3478:
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupFour);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupFour);
                break;
            case FINAL:
                playerModule1.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupRunnerUp);
                playerModule2.rankLevelUp(TopAreanHandle.TopAreanLevel.GroupRunnerUp);
                break;
            default:
                break;
        }
        playerModule1.set();
        playerModule2.set();
    }

    /**
     * 匹配组
     */
    public HashMap<TopAreanHandle.TopAreanCode, TopAreanStructure> matchGroup(int groupId) {
        if(groupId == 0){
            groupId = 9;
        }
        switch (groupId) {
            case 1:
                return getGroup1();
            case 2:
                return getGroup2();
            case 3:
                return getGroup3();
            case 4:
                return getGroup4();
            case 5:
                return getGroup5();
            case 6:
                return getGroup6();
            case 7:
                return getGroup7();
            case 8:
                return getGroup8();
            case 9:
                return getFinals();//冠军赛组
            default:
                break;
        }
        return null;
    }


    /**
     * 战斗
     *
     * @param groupId 第几组
     */
    public TopAreanStructure handleBattle(TopAreanHandle.TopAreanCode topAreanCode, int groupId) {
        TopAreanStructure topAreanStructure = matchGroup(groupId).get(topAreanCode);
        BattleModule battleModule = new TopAreanHandle().handleBattle(topAreanStructure.getPlayer1().getPlayerCode(), topAreanStructure.getPlayer2().getPlayerCode());
        boolean isWin = battleModule.getBattleResult().equals(BattleResult.LEFT_WIN);
        topAreanStructure.setWinner(isWin ? topAreanStructure.getPlayer1() : topAreanStructure.getPlayer2());
        // 处理录像
        {
            String recordCode = String.format("topArean:%s:%s:%s", getAreaId(),groupId,topAreanCode.name());
            battleModule.saveRecord(recordCode);
            topAreanStructure.setRecord(recordCode);
        }
        // 结算竞猜
        rewardFans(topAreanStructure,groupId);

        return topAreanStructure;
    }

    /**
     * 结算竞猜
     */
    private void rewardFans(TopAreanStructure topAreanStructure,int groupid) {
        logger.info("%s区:%s组:%s状态的竞技场巅峰竞猜奖励发放:begin", getAreaId(),groupid,getState());
        TopAreanHandle.TopAreanCode finalCode = topAreanStructure.getFinalCode();
        dfsjingcai data = topAreanStructure.data(groupid);
        Currencies rewards = new Currencies(Currency.create(data.getRewardtype(), data.getRewardid(), data.getRewardnum()));
        String title = GameString.巅峰赛竞猜奖励_titl().getText();
        String content = GameString.巅峰赛竞猜奖励_msg().getText();
        for (String playerCode : topAreanStructure.getWinner().getFans()) {
            logger.info("巅峰赛竞猜奖励发放给玩家:%s", playerCode);
            new MailHandle().sendMail(playerCode, MailTypeEnum.Mail, title, content, CCReason.巅峰赛, rewards);
        }
        logger.info("%s区:第%s组:%s状态的竞技场巅峰竞猜奖励发放:end", getAreaId(),groupid,getState());
    }

    //======================================= redis
    public static TopAreanModule get(int areaId) {
        try {
            TopAreanModule module = getv(key(areaId));
            if (module == null) {
                module = create(areaId);
            }
            return module;
        } catch (RedisException e) {
            e.printStackTrace();
        }
        return null;
    }

    //初始化
    private static TopAreanModule create(int areaId) {
        logger.info("日志7：%s新区,巅峰赛初始化", areaId);
        TopAreanModule module = new TopAreanModule();
        module.setAreaId(areaId);
        module.resetState(DateTime.now().withTimeAtStartOfDay());//重置活动
        return module;
    }

    public void set() {
        try {
            setv(key(getAreaId()), this);
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    static private String key(int areaId) {
        return String.format("AREA:%s:MODULE:TOPAREAN", areaId);
    }

    public static RedisLock lock(int areaId) {
        return getLock(String.format("lock:%s", key(areaId)));
    }

    @Override
    public String lockKey() {
        return String.format("lock:%s", key(getAreaId()));
    }
}
